package com.ruoyi.common.enums;

import java.util.Arrays;
import java.util.List;

/**
 * base enum
 *
 * @author ruoyi
 **/
public interface BaseEnum<C, V> {

    /**
     * Getter method for property <tt>code</tt>.
     *
     * @return property value of code
     */
    C getCode();

    /**
     * Getter method for property <tt>desc</tt>.
     *
     * @return property value of desc
     */
    V getDesc();

    @SafeVarargs
    static <T extends Enum & BaseEnum> boolean in(T target, T... t) {
        Enum[] all = target.getClass().getEnumConstants();

        if (all.length >= 64) {
            List<T> list = Arrays.asList(t);
            return Arrays.stream(all)
                    .map(BaseEnum.class::cast)
                    .anyMatch(list::contains);
        }
        return maskIn(toMask(t), target);
    }

    @SafeVarargs
    static <T extends BaseEnum> long toMask(T... t) {
        if (t == null) {
            return 0L;
        }
        long value = 0L;
        for (T t1 : t) {
            value |= t1.getMask();
        }
        return value;
    }

    @SafeVarargs
    static <T extends BaseEnum> boolean maskIn(long mask, T... t) {
        long value = toMask(t);
        return (mask & value) == value;
    }

    /**
     * @return 枚举序号, 如果枚举顺序改变, 此值将被变动
     */
    int ordinal();

    default long index() {
        return ordinal();
    }

    default long getMask() {
        return 1L << index();
    }
}
